
var mqtt = require('./mqtt.min.js')
const crypto = require('./hex_hmac_sha1.js');

function doConnect() {
  const deviceConfig = {
    productKey: "a1AhmyNokVL",
    deviceName: "weapp",
    deviceSecret: "RAUl3RfqgKwge1OjRIRCyQNY8sIegqEA",
    regionId: "cn-shanghai"
  };
  const options = initMqttOptions(deviceConfig);
  console.log(options)
  //替换productKey为你自己的产品的
  const client = mqtt.connect('wxs://' + deviceConfig.productKey + '.iot-as-mqtt.cn-shanghai.aliyuncs.com', options)
  client.on('connect', function () {
    console.log('连接服务器成功')
    //订阅主题，替换productKey和deviceName
    var topicTmp = '/' + deviceConfig.productKey + '/' + deviceConfig.deviceName + '/user/get'
    client.subscribe(topicTmp, function (err) {
      if (!err) {
        console.log('订阅成功')
        //这里其实不能发布的，需要后台设置权限，请参考阿里云官方文档
      //  client.publish('/' + deviceConfig.productKey + '/' + deviceConfig.deviceName + '/user/update', 'Hello mqtt')
        client.publish(topicTmp, 'Hello mqtt')
        
      }
    })
  })
  //接收消息
  client.on('message', function (topic, message) {
    // message is Buffer
    console.log('收到消息：' + message.toString())
    //关闭连接 client.end()
  })
}

//IoT平台mqtt连接参数初始化
function initMqttOptions(deviceConfig) {
  const params = {
    productKey: deviceConfig.productKey,
    deviceName: deviceConfig.deviceName,
    timestamp: Date.now(),
    clientId: Math.random().toString(36).substr(2),
  }
  //CONNECT参数
  const options = {
    keepalive: 60, //60s
    clean: true, //cleanSession不保持持久会话
    protocolVersion: 4 //MQTT v3.1.1
  }
  //1.生成clientId，username，password
  options.password = signHmacSha1(params, deviceConfig.deviceSecret);
  options.clientId = `${params.clientId}|securemode=2,signmethod=hmacsha1,timestamp=${params.timestamp}|`;
  options.username = `${params.deviceName}&${params.productKey}`;

  return options;
}

/*
  生成基于HmacSha1的password
  参考文档：https://help.aliyun.com/document_detail/73742.html?#h2-url-1
*/
function signHmacSha1(params, deviceSecret) {
  let keys = Object.keys(params).sort();
  // 按字典序排序
  keys = keys.sort();
  const list = [];
  keys.map((key) => {
    list.push(`${key}${params[key]}`);
  });
  const contentStr = list.join('');
  console.log(contentStr);
  return crypto.hex_hmac_sha1(deviceSecret, contentStr);
}
var token

function CloudHttp(productKey, deviceName, deviceSecret) {
  this.productKey = productKey
  this.deviceName = deviceName
  this.deviceSecret = deviceSecret
  this.regionId = 'cn-shanghai'
}

CloudHttp.prototype.connect = function () {
  const deviceConfig = {
    productKey: this.productKey,
    deviceName: this.deviceName,
    deviceSecret: this.deviceSecret,
    signmethod: 'hmacsha1',
    version: 'default',
    regionId: this.regionId,
  };
  const options = initHttpOptions(deviceConfig);
  console.log(options)
  //替换productKey为你自己的产品的
  return new Promise(function (resolve, reject) {
    wx.request({
      url: `https://iot-as-http.${deviceConfig.regionId}.aliyuncs.com/auth`, // 仅为示例，并非真实的接口地址
      data: {
        "productKey": options.productKey,
        "deviceName": options.deviceName,
        "clientId": options.clientId,
        "timestamp": options.timestamp,
        "sign": options.sign,
        "signmethod": options.signmethod,
        "version": options.version
      },
      header: {
        'content-type': 'application/json' // 默认值
      },
      method: 'POST',
      success(res) {
        console.log(res.data)
        token = res.data.info.token
        resolve()
      }
    })
  })
}

CloudHttp.prototype.pubLish = function (topic, data) {
  wx.request({
    url: `https://iot-as-http.${this.regionId}.aliyuncs.com`+
    `/topic/${this.productKey}/${this.deviceName}${topic}`, // 仅为示例，并非真实的接口地址
    data: {
      data
    },
    header: {
      password: token,
      'content-type': 'application/octet-stream' // 默认值
    },
    method: 'POST',
    success(res) {
      console.log(res.data)
    }
  })
}

//IoT平台http连接参数初始化
function initHttpOptions(deviceConfig) {
  const params = {
    productKey: deviceConfig.productKey,
    deviceName: deviceConfig.deviceName,
    clientId: Math.random().toString(36).substr(2),
    timestamp: Date.now(),
  }
  //CONNECT参数
  const options = {}
  //1.生成clientId，username，password
  options.productKey = params.productKey,
  options.deviceName = params.deviceName,
  options.clientId = params.clientId,
  options.timestamp = params.timestamp,
  options.signmethod = deviceConfig.signmethod,
  options.version = deviceConfig.version,
  options.sign = signHmacSha1(params, deviceConfig.deviceSecret);

  return options;
}

var Base64 = {
  _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
  encode: function (e) {
    var t = "";
    var n, r, i, s, o, u, a;
    var f = 0;
    e = Base64._utf8_encode(e);
    while (f < e.length) {
      n = e.charCodeAt(f++);
      r = e.charCodeAt(f++);
      i = e.charCodeAt(f++);
      s = n >> 2;
      o = (n & 3) << 4 | r >> 4;
      u = (r & 15) << 2 | i >> 6;
      a = i & 63;
      if (isNaN(r)) {
        u = a = 64
      } else if (isNaN(i)) {
        a = 64
      }
      t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
    }
    return t
  },
  decode: function (e) {
    var t = "";
    var n, r, i;
    var s, o, u, a;
    var f = 0;
    e = e.replace(/[^A-Za-z0-9+/=]/g, "");
    while (f < e.length) {
      s = this._keyStr.indexOf(e.charAt(f++));
      o = this._keyStr.indexOf(e.charAt(f++));
      u = this._keyStr.indexOf(e.charAt(f++));
      a = this._keyStr.indexOf(e.charAt(f++));
      n = s << 2 | o >> 4;
      r = (o & 15) << 4 | u >> 2;
      i = (u & 3) << 6 | a;
      t = t + String.fromCharCode(n);
      if (u != 64) {
        t = t + String.fromCharCode(r)
      }
      if (a != 64) {
        t = t + String.fromCharCode(i)
      }
    }
    t = Base64._utf8_decode(t);
    return t
  },
  _utf8_encode: function (e) {
    e = e.replace(/rn/g, "n");
    var t = "";
    for (var n = 0; n < e.length; n++) {
      var r = e.charCodeAt(n);
      if (r < 128) {
        t += String.fromCharCode(r)
      } else if (r > 127 && r < 2048) {
        t += String.fromCharCode(r >> 6 | 192);
        t += String.fromCharCode(r & 63 | 128)
      } else {
        t += String.fromCharCode(r >> 12 | 224);
        t += String.fromCharCode(r >> 6 & 63 | 128);
        t += String.fromCharCode(r & 63 | 128)
      }
    }
    return t
  },
  _utf8_decode: function (e) {
    var t = "";
    var n = 0;
    var r = c1 = c2 = 0;
    while (n < e.length) {
      r = e.charCodeAt(n);
      if (r < 128) {
        t += String.fromCharCode(r);
        n++
      } else if (r > 191 && r < 224) {
        c2 = e.charCodeAt(n + 1);
        t += String.fromCharCode((r & 31) << 6 | c2 & 63);
        n += 2
      } else {
        c2 = e.charCodeAt(n + 1);
        c3 = e.charCodeAt(n + 2);
        t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
        n += 3
      }
    }
    return t
  }
}

module.exports = {
  doConnect: doConnect,
  CloudHttp: CloudHttp
}